/*mytop命令*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <utmp.h>
/*@-skipposixheaders@*/
#include <dirent.h>
#include "sys/stat.h"
#include <pwd.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sysinfo.h>
#include <errno.h>
#include <CUnit/Basic.h>
#define STREQ(A,B) (0==strcmp((A),(B)))

/*进程信息结构体*/
struct ProcessInfo {
    int pid;
    char *user;
    int priority;
    int nice;
    long virt_memory;
    long res_memory;
    long shr_memory;
    char state;
    float cpu_usage;
    float mem_usage;
    char *time;
    char *command;
    struct ProcessInfo *next;
};

static unsigned long total_memory = 0;

int compare_process(const void *a, const void *b) {
    float cpu_usage_a = ((struct ProcessInfo *)b)->cpu_usage;
    float cpu_usage_b = ((struct ProcessInfo *)a)->cpu_usage;

    // 降序排序
    if (cpu_usage_a > cpu_usage_b) return -1;
    if (cpu_usage_a < cpu_usage_b) return 1;
    return 0;
}

void parseStartTime(long long int time, char **result)
{
    // 解析 time，将其转换为可读的格式,秒数按60
    int hours, minutes, seconds;
    hours = (int)(time / 3600);
    minutes = (int)((time - hours * 3600) / 60);
    seconds = (int)(time - hours * 3600 - minutes * 60);
    // 分配内存来存储时间字符串
    char *ptime = (char *)malloc(16);
    if(ptime != NULL){
        int  res = snprintf(ptime, 16, "%01d:%02d.%02d", hours, minutes, seconds);
        if(res< 0){
             fprintf(stderr, "Error.\n");
        }
    }
    if(ptime != NULL)
        *result = ptime;
}

 void getProcessPUTC(struct ProcessInfo **process)
{
    DIR *procdir = opendir("/proc");  
    if (procdir == NULL) {  
        perror("Failed to open /proc directory");  
        exit(EXIT_FAILURE);  
    }  
    struct dirent *entry = NULL;  
    while ((entry = readdir(procdir)) != NULL)
    {
        char path[512];
        int re = snprintf(path, sizeof(path), "/proc/%s", entry->d_name);
        if(re< 0){
            fprintf(stderr, "Error.\n");
       }
        struct stat statbuf;
        memset(&statbuf, 0, sizeof(struct stat));
        if (stat(path, &statbuf) == 0 && S_ISDIR(statbuf.st_mode))
        {
            int pid = atoi(entry->d_name);
            if (pid > 0)
            {
                struct ProcessInfo *newProcess = (struct ProcessInfo *)malloc(sizeof(struct ProcessInfo));
                if (newProcess != NULL) {
                    memset(newProcess, 0, sizeof(struct ProcessInfo)); 
                }

                if (newProcess != NULL) {
                    newProcess->pid = pid;

                char statusPath[512];
                int res = snprintf(statusPath, sizeof(statusPath), "/proc/%d/status", pid);
                if(res< 0){
                    fprintf(stderr, "Error.\n");
                }
                FILE *statusFile = fopen(statusPath, "r");
                if (statusFile != NULL)
                {
                    char line[256];
                    while (fgets(line, (int)sizeof(line), statusFile))
                    {
                        if (strstr(line, "Uid:") == line)
                        {
                            uid_t euid, ruid;
                            if (sscanf(line, "Uid:\t%u\t%u", (unsigned int*)&euid, (unsigned int*)&ruid) == 2)
                            {
                                if (euid == 0 || ruid == 0)
                                {
                                    free(newProcess->user);
                                    newProcess->user = strdup("root");
                                }
                                else
                                {
                                    struct passwd *pwd = getpwuid(euid);
                                    if (pwd != NULL)
                                    {
                                        if (newProcess->user != NULL) {
                                            free(newProcess->user);
                                        }
                                        newProcess->user = strdup(pwd->pw_name);
                                        
                                    }
                                }
                            }
                            break;
                        }
                        else if (strstr(line, "Name:") == line)
                        {
                            char cmd[256];
                            if (sscanf(line, "Name:\t%255s", cmd) == 1)
                            {
                                if (newProcess->command != NULL) {
                                    free(newProcess->command);
                                }
                                newProcess->command = strdup(cmd);
                            }
                        }
                    }
                }
                char statPath[512];
                int ret = snprintf(statPath, sizeof(statPath), "/proc/%d/stat", pid);
                if(ret< 0){
                    fprintf(stderr, "Error.\n");
                }
                FILE *statFile = fopen(statPath, "r");
                if (statFile != NULL)
                {
                    unsigned long int utime, stime;
                    int ret1 = fscanf(statFile, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*lu %*lu %*lu %*lu %lu %lu", &utime, &stime);
                    {
                        parseStartTime((long long)utime + stime, &newProcess->time);
                    }
                    if (ret1 == EOF) {  
                        perror("error");
                    } 
                    int ret2 = fclose(statFile);
                    if (ret2 != 0) {  
                        perror("error");
                    } 
                }

                if(newProcess->next != NULL){
                    free(newProcess->next);
                    newProcess->next = NULL;
                }
                if (*process == NULL)
                {
                    *process = newProcess;
                }
                else
                {
                    struct ProcessInfo *tail = *process;
                    while (tail->next != NULL)
                    {
                        tail = tail->next;
                    }
                    tail->next = newProcess;
                }
                if(statusFile != NULL)
                    { 
                        int ret3 = fclose(statusFile);
                        if (ret3 != 0) {  
                        perror("error");
                    } 
                    }
            }
            }
        }
    }
    
    int ret4 = closedir(procdir);
    if (ret4 != 0) {  
        perror("error");
    } 
    if (*process == NULL || (*process)->next == NULL) {
       exit(EXIT_FAILURE);
    }
}

void getProcessInfo(struct ProcessInfo *process)
{
    DIR *procdir = opendir("/proc");
    if (procdir == NULL)
    {
        perror("Failed to open /proc directory");
        exit(EXIT_FAILURE);
    }

    struct dirent *entry;
    struct ProcessInfo *processpid = process;
    while ((entry = readdir(procdir)) != NULL)
    {
        char path[512];
        int res = snprintf(path, sizeof(path), "/proc/%s", entry->d_name);
        if(res < 0){
          fprintf(stderr, "Error.\n");
        }
        struct stat statbuf;
        memset(&statbuf, 0, sizeof(struct stat));
        if (stat(path, &statbuf) == 0 && S_ISDIR(statbuf.st_mode))
        {
            int pid = atoi(entry->d_name);
            if (pid > 0)
            {
                while (processpid != NULL)
                {
                    if (processpid->pid == pid)
                    {
                        char stat_path[512];
                        int ret = snprintf(stat_path, sizeof(stat_path), "/proc/%d/stat", pid);
                        if(ret< 0){
                             fprintf(stderr, "Error.\n");
                        }
                        FILE *stat_file = fopen(stat_path, "r");
                        if (stat_file != NULL)
                        {
                            char stat_buffer[1024];
                            if (fgets(stat_buffer, (int)sizeof(stat_buffer), stat_file) != NULL)
                            {
                                (void)sscanf(stat_buffer, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %*u %*d %*d %*d %d %d", &(processpid->priority), &(processpid->nice));
                            }

                            int ret5 = fclose(stat_file);
                            if (ret5 != 0) {  
                                perror("error");
                            } 
                        }

                        char status_path[512];
                        int res6 = snprintf(status_path, sizeof(status_path), "/proc/%d/status", pid);
                        if(res6 < 0){
                            fprintf(stderr, "Error.\n");
                        }
                        FILE *status_file = fopen(status_path, "r");
                        if (status_file != NULL)
                        {
                            char line[256];
                            while (fgets(line, (int)sizeof(line), status_file))
                            {
                                if (strstr(line, "State:") == line)
                                {
                                    char state;
                                    if (sscanf(line, "State:\t%c", &state) == 1)
                                    {
                                        processpid->state = state;
                                    }
                                }
                                else if (strstr(line, "RssFile:") == line)
                                {
                                    long shr = 0;
                                    if (sscanf(line, "RssFile:\t%ld", &shr) == 1)
                                    {
                                        processpid->shr_memory = shr;
                                    }
                                }
                            }

                            int ret7 = fclose(status_file);
                            if (ret7 != 0) {  
                                perror("error");
                            } 
                        }

                        process = processpid;
                        break;
                    }
                    processpid = processpid->next;
                }
            }
        }
    }

    int ret8 = closedir(procdir);
    if (ret8 != 0) {  
       perror("error");
    } 
}

void getProcessCPUMem(struct ProcessInfo *process) {
    DIR *procdir = opendir("/proc");
    if (procdir == NULL) {
        perror("Failed to open /proc directory");
        exit(EXIT_FAILURE);
    }

    struct dirent *entry;
    struct ProcessInfo *processpid = process;
    while ((entry = readdir(procdir)) != NULL) {
        char path[512];
        int res = snprintf(path, sizeof(path), "/proc/%s", entry->d_name);
        if(res < 0){
           fprintf(stderr, "Error creating stat_path or path is too long.\n");
        }
        struct stat statbuf;
        memset(&statbuf, 0, sizeof(struct stat));
        if (stat(path, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) {
            int pid = atoi(entry->d_name);
            if (pid > 0) {
                while (processpid != NULL) {
                    if (processpid->pid == pid) 
                    {
                            char status_path[512];
                            int ret = snprintf(status_path, sizeof(status_path), "/proc/%d/status", pid);
                            if(ret < 0){
                                fprintf(stderr, "Error\n");
                            }
                            FILE *status_file = fopen(status_path, "r");
                            if (status_file == NULL)
                            {
                                perror("Failed to open status file");
                                exit(EXIT_FAILURE);
                            }


                            long vm_size = 0; //vm_hwm = 0,
                            long vm_rss = 0;
                            char line[256];

                            while (fgets(line, (int)sizeof(line), status_file))
                                {
                                    if (strstr(line, "VmSize:") == line)
                                    {
                                        (void)sscanf(line, "VmSize:\t%ld kB", &vm_size);
                                        }
                                    else if (strstr(line, "VmRSS:") == line)
                                    {
                                        (void)sscanf(line, "VmRSS:\t%ld kB", &vm_rss);
                                    }

                                }

                            if (vm_size >= 0)
                                {
                                    processpid->virt_memory = vm_size;
                                    processpid->mem_usage = ((float)vm_rss /(float)total_memory) * 100 ;
                                }
                            else
                                {
                                    processpid->mem_usage = 0.0;
                                }
                            if (vm_rss >= 0)
                                {
                                    processpid->res_memory = vm_rss;
                                }
                                else
                                {
                                    fprintf(stderr, "Failed to parse VmHWM value\n");
                                }
                            int ret9 = fclose(status_file);
                            if (ret9 != 0) {  
                                perror("error");
                            } 

                            char stat_path[512];
                            int result = snprintf(stat_path, sizeof(stat_path), "/proc/%d/stat", pid);
                            if(result < 0)
                                {
                                    fprintf(stderr, "Error creating stat_path or path is too long.\n");
                                }
                            FILE *stat_file = fopen(stat_path, "r");
                            if (stat_file == NULL)
                                {
                                    perror("Failed to open stat file");
                                        exit(EXIT_FAILURE);
                                }
                            unsigned long utime, stime;
                            if (fscanf(stat_file, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*lu %*lu %*lu %*lu %lu %lu", &utime, &stime) == 2)
                                {
                                    unsigned long total_time = utime + stime;
                                    float cpu_usage = ((float)total_time / 10);
                                    processpid->cpu_usage = cpu_usage - processpid->cpu_usage;
                                }
                        int ret10 = fclose(stat_file);
                        if (ret10 != 0) {  
                                perror("error");
                            } 
                        process = processpid; 
                        break;
                                            
                    } 
                        processpid = processpid->next;
                    }
                }
            }
    }
        int ret11 = closedir(procdir);
        if (ret11 != 0) {  
            perror("error");
        } 
}

void Print(struct ProcessInfo *process)
{
    struct ProcessInfo *current = process;
    
    printf("PID \tUSER \tPR \tNI \tVIRT \tRES \tSHR \tS \t%%CPU \t%%MEM \tTIME+ \t\tCOMMAND\n");
    int count = 20;
    while (current != NULL && count != 0)
    {
        count--;
        printf("%d\t", current->pid);
        printf("%s\t", current->user);
        if(current->priority == -100){
            printf("rt\t");
        }else{
            printf("%d\t", current->priority);
        }
        printf("%d\t", current->nice);
        if( current->virt_memory > 1024*1024*1024){
            printf("%.1ft\t", (double)current->virt_memory/(1024*1024*1024));
        }else if(current->virt_memory > 9999999){
            printf("%.1fg\t", (double)current->virt_memory/(1024*1024));
        }else{
            printf("%ld\t",current->virt_memory);
        }
        printf("%ld\t", current->res_memory);
        printf("%ld\t", current->shr_memory);
        printf("%c\t", current->state);
        printf("%.1f\t", current->cpu_usage);
        printf("%.1f\t", current->mem_usage);
        printf("%s\t\t", current->time);
        printf("%s\t", current->command);
        printf("\n");

        current = current->next;
    }
}

void gettime()
{
    time_t timep;

    struct tm *p;

    char time1[28];

    (void)time (&timep);

    p=localtime(&timep);

    char time2[10];

    (void)snprintf(time1,sizeof(time2), "%02d:%02d:%02d",p->tm_hour,p->tm_min,p->tm_sec);

    printf("top - %s ",time1);
}
void getRunTime()
{
    struct sysinfo info;
    char run_time[128];
 
    if (sysinfo(&info)) {  
    fprintf(stderr, "Failed to get sysinfo, errno:%u, reason:%s\n", (unsigned int)errno, strerror(errno));  
    perror("sysinfo");  
}
 
     long timenum=info.uptime;
    int runhour=(timenum%86400)/3600;
    int runmin=(timenum%3600)/60;
    bzero(run_time, 128);
 
    sprintf(run_time,"%d:%02d",runhour,runmin);
    printf(" up %s ,  ",run_time);
}
void getUserNum ()
{
    struct utmp *u;
    int count = 0;
    setutent();
    while ((u = getutent()) != NULL) {
        if (u->ut_line[0] == '~') continue;
        if (u->ut_user[0] && (!STREQ(u->ut_user, "LOGIN")) ) {
            count++;
        }
    }
    endutent();
    printf("%d user,  ", count);
}

void getLoadavg() {
    double loadavg[3];
    int ret = getloadavg(loadavg, 3);
    if (ret == -1) {
        perror("getloadavg");
        exit(EXIT_FAILURE);
    }

    printf("load average: %.2f, %.2f, %.2f\n", loadavg[0],loadavg[1],loadavg[2]);
}

//进程信息
void getProcessCounts(int *totalCount, int *runningCount, int *sleepingCount, int *stoppedCount, int *zombieCount) {
    *totalCount = 0;
    *runningCount = 0;
    *sleepingCount = 0;
    *stoppedCount = 0;
    *zombieCount = 0;

    DIR *dir = opendir("/proc");
    if (dir == NULL) {
        perror("opendir");
        exit(EXIT_FAILURE);
    }

    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL) {
        if (entry->d_type == DT_DIR ) {
            char *endptr;
            long int pid = strtol(entry->d_name, &endptr, 10);
            if (*endptr == '\0') {
                (*totalCount)++;

                char statFilePath[256];
                snprintf(statFilePath, sizeof(statFilePath), "/proc/%ld/stat", pid);

                FILE *statFile = fopen(statFilePath, "r");
                if (statFile) {
                    char statContent[1024];
                    if (fgets(statContent, sizeof(statContent), statFile)) {
                        fclose(statFile);

                        char state;
                        (void)sscanf(statContent, "%*d %*s %c", &state);
                        switch (state) {
                            case 'R':
                                (*runningCount)++;
                                break;
                            case 'S':
                                (*sleepingCount)++;
                                break;
                            case 'I':
                                (*sleepingCount)++;
                                break;
                            case 'D':
                                (*sleepingCount)++;
                                break;
                            case 'T':
                                (*stoppedCount)++;
                                break;
                            case 'Z':
                                (*zombieCount)++;
                                break;
                            default:
                                break;
                        }
                    }
                }
            }
        }
    }

    closedir(dir);
}
void printProcessCount()
{
    int totalCount, runningCount, sleepingCount, stoppedCount, zombieCount;
    getProcessCounts(&totalCount, &runningCount, &sleepingCount, &stoppedCount, &zombieCount);
    printf("tasks: %d total,  %d running, %d sleeping,  %d stopped,  %d zombie\n", totalCount,runningCount,sleepingCount,stoppedCount,zombieCount);
}
//cpu
void getCpuStats(double* user, double* nice, double* system, double* idle, double* iowait, double* irq, double* softirq, double* steal, double* hardirq) {  
    FILE* statFile = fopen("/proc/stat", "r");  
    if (statFile == NULL) {  
        perror("fopen");  
        exit(EXIT_FAILURE);  
    }  
  
    char line[256];  
    while (fgets(line, sizeof(line), statFile)) {  
        if (strncmp(line, "cpu ", 4) == 0) {  
            (void)sscanf(line + 5, "%lf %lf %lf %lf %lf %lf %lf %lf %lf", user, nice, system, idle, iowait, irq, softirq, steal, hardirq);  
            break;  
        }  
    }  
  
    fclose(statFile);  
}  
  
double getTotalCpuTime(double user, double nice, double system, double idle, double iowait, double irq, double softirq, double steal, double hardirq) {  
    double totalCpuTime = user + nice + system + idle + iowait + irq + softirq + steal + hardirq;  
    if(totalCpuTime < 0) {  
        printf("Error: Total CPU time is negative\n");  
        return 0;  
    }  
    return totalCpuTime;  
}  
  
void printCpuStats() {  
    double user = 0.0, nice = 0.0, system = 0.0, idle = 0.0, iowait = 0.0, irq = 0.0, softirq = 0.0, steal = 0.0, hardirq = 0.0;  
    getCpuStats(&user, &nice, &system, &idle, &iowait, &irq, &softirq, &steal, &hardirq);  
  
    double totalCpuTime = getTotalCpuTime(user, nice, system, idle, iowait, irq, softirq, steal, hardirq);  
  
    double userPercent = (user / totalCpuTime) * 100;  
    double nicePercent = (nice / totalCpuTime) * 100;  
    double systemPercent = ((system + irq + softirq + hardirq) / totalCpuTime) * 100;  
    double idlePercent = (idle / totalCpuTime) * 100;  
    double iowaitPercent = (iowait / totalCpuTime) * 100;  
    double stealPercent = (steal / totalCpuTime) * 100;  
    double hardirqPercent = (hardirq / totalCpuTime) * 100;  
    double softirqPercent = (softirq / totalCpuTime) * 100;  
  
    printf("%%Cpu(s): %.1lf us, %.1lf sy, %.1lf ni, %.1lf id, %.1lf wa, %.1lf hi, %.1lf si, %.1lf st\n", userPercent, systemPercent, nicePercent, idlePercent, iowaitPercent, hardirqPercent, softirqPercent, stealPercent);  
}

//内存状态信息
void printMemoryInfo(unsigned long long total, unsigned long long free, unsigned long long used, unsigned long long buffCache) {
    printf("MiB Mem : %8.1f total, %8.1f free, %8.1f used, %8.1f buff/cache\n",
           total / 1024.0, free / 1024.0, used / 1024.0, buffCache / 1024.0);
}

void printSwapInfo(unsigned long long total, unsigned long long free, unsigned long long used, unsigned long long availMem) {
    printf("MiB Swap: %8.1f total, %8.1f free, %8.1f used, %8.1f avail Mem\n",
           total / 1024.0, free / 1024.0, used / 1024.0, availMem / 1024.0);
}

void getMemoryInfo(unsigned long long* total, unsigned long long* free, unsigned long long* used, unsigned long long* buffCache) {
    FILE* memInfoFile = fopen("/proc/meminfo", "r");
    if (memInfoFile == NULL) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }

    char line[256];
    while (fgets(line, sizeof(line), memInfoFile)) {
        if (strncmp(line, "MemTotal:", 9) == 0) {
            (void)sscanf(line + 9, "%llu", total);
        } else if (strncmp(line, "MemFree:", 8) == 0) {
            (void)sscanf(line + 8, "%llu", free);
        } else if (strncmp(line, "Buffers:", 8) == 0) {
            (void)sscanf(line + 8, "%llu", buffCache);
        } else if (strncmp(line, "Cached:", 7) == 0) {
            unsigned long long cached;
            (void)sscanf(line + 7, "%llu", &cached);
            *buffCache += cached;
        }
    }

    fclose(memInfoFile);

    *used = *total - *free - *buffCache;
}

void getSwapInfo(unsigned long long* total, unsigned long long* free, unsigned long long* used, unsigned long long* availMem) {
    FILE* memInfoFile = fopen("/proc/meminfo", "r");
    if (memInfoFile == NULL) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }

    char line[256];
    while (fgets(line, sizeof(line), memInfoFile)) {
        if (strncmp(line, "SwapTotal:", 10) == 0) {
            (void)sscanf(line + 10, "%llu", total);
        } else if (strncmp(line, "SwapFree:", 9) == 0) {
            (void)sscanf(line + 9, "%llu", free);
        } else if (strncmp(line, "MemAvailable:", 13) == 0) {
            (void)sscanf(line + 13, "%llu", availMem);
        }
        (void)sscanf(line, "MemTotal: %lu kB", &total_memory);
    }
    
    fclose(memInfoFile);

    *used = *total - *free;
}

void printSwap()
{
    unsigned long long memTotal = 0, memFree = 0, memUsed = 0, buffCache = 0;
    getMemoryInfo(&memTotal, &memFree, &memUsed, &buffCache);
    printMemoryInfo(memTotal, memFree, memUsed, buffCache);

    unsigned long long swapTotal = 0, swapFree = 0, swapUsed = 0, availMem = 0;
    getSwapInfo(&swapTotal, &swapFree, &swapUsed, &availMem);
    printSwapInfo(swapTotal, swapFree, swapUsed, availMem);
}

static FILE *temp_file = NULL;

int init_suite1(void)
{
   if (NULL == (temp_file = fopen("mytop.c", "w+")))
   {
      return -1;
   }
   else
   {
      return 0;
   }
}

/* The suite cleanup function.
 * Closes the temporary file used by the tests.
 * Returns zero on success, non-zero otherwise.
 */
/* 第一步 套件初始化 编写clean套件*/
int clean_suite1(void)
{
   if (0 != fclose(temp_file))
   {
      return -1;
   }
   else
   {
      temp_file = NULL;
      return 0;
   }
}


void testcompare_process(void)
{
    int result = compare_process;
   //满足判定覆盖标准的测试用例
   CU_ASSERT(result);
}

void testparseStartTime(void)
{
    int result = parseStartTime;
   //满足判定覆盖标准的测试用例
   CU_ASSERT(result);
}

void testgetProcessPUTC(void)
{
    int result = getProcessPUTC;
   //满足判定覆盖标准的测试用例
   CU_ASSERT(result);
}

void testgetProcessInfo(void)
{
    int result = getProcessInfo;
   //满足判定覆盖标准的测试用例
   CU_ASSERT(result);
}

void testgetProcessCPUMem(void)
{
    int result = getProcessCPUMem;
   //满足判定覆盖标准的测试用例
   CU_ASSERT(result);
}

void testgetProcessCounts(void)
{
    int result = getProcessCounts;
   //满足判定覆盖标准的测试用例
   CU_ASSERT(result);
}

void testgetMemoryInfo(void)
{
    int result = getMemoryInfo;
   //满足判定覆盖标准的测试用例
   CU_ASSERT(result);
}

void testgetSwapInfo(void)
{
    int result = getSwapInfo;
   //满足判定覆盖标准的测试用例
   CU_ASSERT(result);
}

/*main函数*/
int main()
{
   CU_pSuite pSuite = NULL; //初始化结构体

   /* initialize the CUnit test registry */
   /* 第二步 初始化注册表 */
   if (CUE_SUCCESS != CU_initialize_registry())
      return CU_get_error();

   /* add a suite to the registry */
   /* 第三步 添加套件到测试注册表 */
   pSuite = CU_add_suite("Suite_1", init_suite1, clean_suite1);
   if (NULL == pSuite)
   {                         // 如果添加套件失败
      CU_cleanup_registry(); // 清理注册表并报错
      return CU_get_error();
   }

   /* add the tests to the suite */
   /* 第四步 添加测试套件 */
   /* NOTE - ORDER IS IMPORTANT - MUST TEST fread() AFTER fprintf() */
   if ((NULL == CU_add_test(pSuite, "test of compare_process()", testcompare_process)) 
    ||(NULL == CU_add_test(pSuite, "test of parseStartTime", testparseStartTime)) ||
         (NULL == CU_add_test(pSuite, "test of getProcessPUTC", testgetProcessPUTC))||
         (NULL == CU_add_test(pSuite, "test of parseStartTime", testparseStartTime))||
         (NULL == CU_add_test(pSuite, "test of getProcessInfo", testgetProcessInfo))||
         (NULL == CU_add_test(pSuite, "test of getProcessCPUMem", testgetProcessCPUMem))||
         (NULL == CU_add_test(pSuite, "test of getProcessCounts", testgetProcessCounts))||
         (NULL == CU_add_test(pSuite, "test of getMemoryInfo", testgetMemoryInfo))||
         (NULL == CU_add_test(pSuite, "test of getSwapInfo", testgetSwapInfo))
   )
   { // 如果添加测试套件失败清理注册表并报错
      CU_cleanup_registry();
      return CU_get_error();
   }

   /* Run all tests using the CUnit Basic interface */
   /* 第五步 使用适当的接口运行测试 */
   /* 
   CU_BRM_NORMAL    Normal模式-失败和运行摘要打印[default]
   CU_BRM_SILENT    静默模式-除了框架错误消息外，不输出任何输出。
   CU_BRM_VERBOSE   详细模式——运行详细信息的最大输出。
   */
   CU_basic_set_mode(CU_BRM_VERBOSE); // 设置基本接口的运行模式
   CU_basic_run_tests(); // 使用基本接口运行所有注册的CUnit测试

   /* 第六步 清理测试注册表 */
   CU_cleanup_registry();
   return CU_get_error();
}
